<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Use constant_keyword to speed up filtering | ElasticSearch 7.7 权威指南中文版</title>
	<meta name="keywords" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <meta name="description" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
	<script>
	var _link = 'faster-filtering-with-constant-keyword.html';
    </script>
</head>
<body>
<div class="main-container">
    <section id="content">
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.7/faster-filtering-with-constant-keyword.html" rel="nofollow" target="_blank">https://www.elastic.co/guide/en/elasticsearch/reference/7.7/faster-filtering-with-constant-keyword.html</a>, 原文档版权归 www.elastic.co 所有<br/>本地英文版地址: <a href="../en/faster-filtering-with-constant-keyword.html" rel="nofollow" target="_blank">../en/faster-filtering-with-constant-keyword.html</a></div>
                        <!-- start body -->
                  <div class="page_header">
<strong>重要</strong>: 此版本不会发布额外的bug修复或文档更新。最新信息请参考 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" rel="nofollow">当前版本文档</a>。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch Guide [7.7]</a></span>
»
<span class="breadcrumb-link"><a href="how-to.html">How To</a></span>
»
<span class="breadcrumb-link"><a href="tune-for-search-speed.html">Tune for search speed</a></span>
»
<span class="breadcrumb-node">Use <a class="xref" href="constant-keyword.html" title="Constant keyword datatype"><code class="literal">constant_keyword</code></a> to speed up filtering</span>
</div>
<div class="navheader">
<span class="prev">
<a href="faster-prefix-queries.html">« Faster prefix queries with <code class="literal">index_prefixes</code></a>
</span>
<span class="next">
<a href="tune-for-disk-usage.html">Tune for disk usage »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="faster-filtering-with-constant-keyword"></a>Use <a class="xref" href="constant-keyword.html" title="Constant keyword datatype"><code class="literal">constant_keyword</code></a> to speed up filtering<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/how-to/search-speed.asciidoc">edit</a>
</h2>
</div></div></div>
<p>There is a general rule that the cost of a filter is mostly a function of the
number of matched documents. Imagine that you have an index containing cycles.
There are a large number of bicycles and many searches perform a filter on
<code class="literal">cycle_type: bicycle</code>. This very common filter is unfortunately also very costly
since it matches most documents. There is a simple way to avoid running this
filter: move bicycles to their own index and filter bicycles by searching this
index instead of adding a filter to the query.</p>
<p>Unfortunately this can make client-side logic tricky, which is where
<code class="literal">constant_keyword</code> helps. By mapping <code class="literal">cycle_type</code> as a <code class="literal">constant_keyword</code> with
value <code class="literal">bicycle</code> on the index that contains bicycles, clients can keep running
the exact same queries as they used to run on the monolithic index and
Elasticsearch will do the right thing on the bicycles index by ignoring filters
on <code class="literal">cycle_type</code> if the value is <code class="literal">bicycle</code> and returning no hits otherwise.</p>
<p>Here is what mappings could look like:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT bicycles
{
  "mappings": {
    "properties": {
      "cycle_type": {
        "type": "constant_keyword",
        "value": "bicycle"
      },
      "name": {
        "type": "text"
      }
    }
  }
}

PUT other_cycles
{
  "mappings": {
    "properties": {
      "cycle_type": {
        "type": "keyword"
      },
      "name": {
        "type": "text"
      }
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1322.console"></div>
<p>We are splitting our index in two: one that will contain only bicycles, and
another one that contains other cycles: unicycles, tricycles, etc. Then at
search time, we need to search both indices, but we don’t need to modify
queries.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET bicycles,other_cycles/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "description": "dutch"
        }
      },
      "filter": {
        "term": {
          "cycle_type": "bicycle"
        }
      }
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1323.console"></div>
<p>On the <code class="literal">bicycles</code> index, Elasticsearch will simply ignore the <code class="literal">cycle_type</code>
filter and rewrite the search request to the one below:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET bicycles,other_cycles/_search
{
  "query": {
    "match": {
      "description": "dutch"
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1324.console"></div>
<p>On the <code class="literal">other_cycles</code> index, Elasticsearch will quickly figure out that
<code class="literal">bicycle</code> doesn’t exist in the terms dictionary of the <code class="literal">cycle_type</code> field and
return a search response with no hits.</p>
<p>This is a powerful way of making queries cheaper by putting common values in a
dedicated index. This idea can also be combined across multiple fields: for
instance if you track the color of each cycle and your <code class="literal">bicycles</code> index ends up
having a majority of black bikes, you could split it into a <code class="literal">bicycles-black</code>
and a <code class="literal">bicycles-other-colors</code> indices.</p>
<p>The <code class="literal">constant_keyword</code> is not strictly required for this optimization: it is
also possible to update the client-side logic in order to route queries to the
relevant indices based on filters. However <code class="literal">constant_keyword</code> makes it
transparently and allows to decouple search requests from the index topology in
exchange of very little overhead.</p>
</div>
<div class="navfooter">
<span class="prev">
<a href="faster-prefix-queries.html">« Faster prefix queries with <code class="literal">index_prefixes</code></a>
</span>
<span class="next">
<a href="tune-for-disk-usage.html">Tune for disk usage »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>